package org.real.guetshop.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.real.guetshop.constant.MessageConstant;
import org.real.guetshop.constant.OrderConstant;
import org.real.guetshop.context.BaseContext;
import org.real.guetshop.controller.general.SSEController;
import org.real.guetshop.exception.AddressBookBusinessException;
import org.real.guetshop.exception.ShoppingCartBusinessException;
import org.real.guetshop.exception.StorageNotEnoughException;
import org.real.guetshop.mapper.OrderMapper;
import org.real.guetshop.mapper.ProductMapper;
import org.real.guetshop.mapper.ShopCartMapper;
import org.real.guetshop.pojo.dto.OrderPageDTO;
import org.real.guetshop.pojo.dto.OrderSubmitDTO;
import org.real.guetshop.pojo.entity.Order;
import org.real.guetshop.pojo.entity.RedisOrder;
import org.real.guetshop.pojo.entity.ShopCart;
import org.real.guetshop.pojo.vo.OrderOldVO;
import org.real.guetshop.result.PageResult;
import org.real.guetshop.service.OrderService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class OrderServiceImpl implements OrderService {

    @Resource
    private OrderMapper orderMapper;

    @Resource
    private ShopCartMapper shopCartMapper;

    @Resource
    private ProductMapper productMapper;

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Resource
    private SSEController sseController;

    /**
     * 用户下单
     * @param orderSubmitDTO
     * @return
     */
    @Override
    @Transactional
    public void submit(OrderSubmitDTO orderSubmitDTO) throws StorageNotEnoughException {

        //处理各种异常(地址为空）
        if (orderSubmitDTO.getAddress().isEmpty()){
            throw new AddressBookBusinessException(MessageConstant.ADDRESS_BOOK_IS_NULL);
        }

        //购物车为空
        ShopCart shopCart = new ShopCart();
        //查询当前购物车数据
        Integer userId = BaseContext.getCurrentId();
        shopCart.setUserId(userId);
        List<ShopCart> shopCartList = shopCartMapper.list(shopCart);

        if (shopCartList == null || shopCartList.isEmpty()){
            throw new ShoppingCartBusinessException(MessageConstant.SHOPPING_CART_IS_NULL);
        }

        for (ShopCart shopCarts : shopCartList) {
            //向订单表插入一条数据
            Order order = Order.builder()
                    .userId(userId)
                    .orderTime(LocalDateTime.now())
                    .status(OrderConstant.NOT_FINISH)
                    .orderNumber(String.valueOf(System.currentTimeMillis()))
                    .phone(orderSubmitDTO.getPhone())
                    .address(orderSubmitDTO.getAddress())
                    .amount(orderSubmitDTO.getAmount())
                    .productId(shopCarts.getProductId())
                    .storeId(shopCarts.getStoreId())
                    .number(shopCarts.getNumber())
                    .name(shopCarts.getName())
                    .unit(shopCarts.getUnit())
                    .username(shopCarts.getUsername())
                    .build();

            if (order.getNumber() >= productMapper.getTotalByProductId(order.getProductId())){
                throw new StorageNotEnoughException("商品 "+order.getName()+" 库存不足");
            }

            String msg = "用户"+order.getUsername()+"购买"+order.getName()+"，数量为"+order.getNumber()+order.getUnit();
            //给商品对应商家发送消息
            sseController.sendMessageToMerchant(order.getStoreId(),msg);

            orderMapper.insert(order);
            productMapper.updateProductTotal(shopCarts.getNumber(),shopCarts.getProductId());
        }

//        Integer orderId = order.getId();
//
//        List<OrderGood> orderGoods = new ArrayList<>();
//        //将购物车表中的数据转移到订单货物表中
//        for (ShopCart shopCart1 : shopCartList) {
//            OrderGood orderGood = new OrderGood();
//            BeanUtils.copyProperties(shopCart1, orderGood);
//            orderGood.setOrderId(orderId);
//            orderGoods.add(orderGood);
//        }
//        //转移到订单货物表
//        shopCartMapper.translate(orderGoods);

        //清空购物车
        shopCartMapper.clean(userId);
        getAndSet(BaseContext.getCurrentId());
    }

    /**
     * 订单完成
     */
    @Override
    public void finish(String orderNumber) {
        Order order = new Order();
        order.setEndTime(LocalDateTime.now());
        order.setStatus(OrderConstant.IS_FINISH);
        order.setOrderNumber(orderNumber);
        orderMapper.finish(order);

        order = orderMapper.getByNumber(orderNumber);

        OrderOldVO orderOldVO = new OrderOldVO();
        BeanUtils.copyProperties(order, orderOldVO);

        getAndSet(BaseContext.getCurrentId());
    }


    /**
     * 查看历史订单
     * @return
     */
    @Override
    public List<OrderOldVO> getHistory() {
        try {
            String userOrdersKey = "orders_" + BaseContext.getCurrentId();
            List<RedisOrder> redisOrders = (List<RedisOrder>) redisTemplate.opsForValue().get(userOrdersKey);
            List<OrderOldVO> orderOldVOS = new ArrayList<>();
            if (redisOrders != null) {
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                for (RedisOrder redisOrder : redisOrders) {
                    OrderOldVO orderOldVO = new OrderOldVO();
                    BeanUtils.copyProperties(redisOrder, orderOldVO);
                    orderOldVO.setOrderTime(LocalDateTime.parse(redisOrder.getOrderTime(), formatter));
                    if (redisOrder.getEndTime() != null){
                        orderOldVO.setEndTime(LocalDateTime.parse(redisOrder.getEndTime(), formatter));
                    }
                    orderOldVOS.add(orderOldVO);
                }
            }else {
                orderOldVOS = orderMapper.getHistory(BaseContext.getCurrentId());
            }
            return orderOldVOS;
        } catch (BeansException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 商家订单分页查询
     * @param orderPageDTO
     * @return
     */
    @Override
    public PageResult getPage(OrderPageDTO orderPageDTO) {
        PageHelper.startPage(orderPageDTO.getPage(), orderPageDTO.getSize());
        Integer storeId = BaseContext.getCurrentId();
        Page<Order> pageResult = orderMapper.page(orderPageDTO,storeId);
        long total = pageResult.getTotal();
        List<Order> records = pageResult.getResult();
        return new PageResult(total, records);
    }
//    /**
//     * 商家分页查询订单
//     * @param orderPageDTO
//     * @return
//     */
//    @Override
//    public PageResult getPage(OrderPageDTO orderPageDTO) {
//        PageHelper.startPage(orderPageDTO.getPage(), orderPageDTO.getSize());
//        Page<OrderOldVO> pageResult = orderMapper.page(orderPageDTO);
//        long total = pageResult.getTotal();
//        List<OrderOldVO> records = pageResult.getResult();
//        return null;
//    }

    /**
     * 对redis里的订单进行操作
     */
    private void getAndSet(Integer userId ){
        String key = "orders_"+userId;
        //清除redis中的数据
        redisTemplate.delete(key);

        //重新查询订单然后存入redis
        List<RedisOrder> redisOrders = orderMapper.selectBatch(BaseContext.getCurrentId());
        redisTemplate.opsForValue().set(key,redisOrders);
        //先查看在redis中用户的数据是否为null
        // 这里假设每个用户的订单用一个哈希表来存储，哈希表的 key 是 "orders_" + 用户ID
//        String userOrdersKey = "orders_" + BaseContext.getCurrentId();
//        List<RedisOrder> redisOrders = (List<RedisOrder>) redisTemplate.opsForValue().get(userOrdersKey);
//
//        //为了解决日期序列化问题
//        RedisOrder redisOrder = new RedisOrder();
//        BeanUtils.copyProperties(orderOldVO, redisOrder);
//        redisOrder.setOrderTime(orderOldVO.getOrderTime().toString());
//
//        redisOrder.setEndTime(orderOldVO.getEndTime().toString());
//        List<RedisOrder> newOrderOldVOS = new ArrayList<>();
//        if (redisOrders == null || redisOrders.isEmpty()){
//            newOrderOldVOS.add(redisOrder);
//
//            redisTemplate.opsForValue().set(userOrdersKey, newOrderOldVOS);
//        }else {
//            //用户的list不为空
//            redisOrders.add(redisOrder);
//            //将完成的订单放入redis
//            redisTemplate.opsForValue().set(userOrdersKey, redisOrders);
//        }
        // 如果需要设置过期时间，可以使用下面的方式：
        // redisTemplate.expire(orderKey, 3600, TimeUnit.SECONDS);
    }
}
